home *** CD-ROM | disk | FTP | other *** search
- /* PRESTO: SLOCK.c
- *
- * The purpose of this module is to provide out-of-line procedure
- * definitions for S_LOCK, etc., since C++ doesn't understand
- * asm-functions. The preferred solution to this problem, however,
- * is to use "CC +h/usr/include/Presto/asmdefs.h file.c";
- * this causes the asm-function definitions to be slipped into
- * file..c before cc is called.
- *
- * This code is lifted straight out of <parallel/parallel.h>.
- * Copyright Sequent Computer, etc.
- */
-
- #ifdef i386
-
- /*
- * A "lock" is a byte of memory, initialized to zero (unlocked).
- */
- typedef unsigned char slock_t;
-
- #define L_UNLOCKED 0
- #define L_LOCKED 1
-
- /*
- * Was a conditional lock request granted (L_SUCCESS) or denied (L_FAILED)
- */
- #define L_FAILED 0
- #define L_SUCCESS 1
-
- /*
- * S_LOCK() S_UNLOCK(), S_CLOCK(), and S_INIT_LOCK functions.
- * These are implemented as "asm functions", and will produce very good code.
- *
- * Need to use the -i flag with the optimizer when these inline functions are
- * used. (cc -O -i). This is to prevent the optimizer from removing
- * "redundant" moves (which aren't really redundant in this case)
- * in the spin loops.
- */
-
- asm void LOCK(laddr)
- {
- %reg laddr; lab loop, spin, done;
- /PEEPOFF
- loop: movb $L_LOCKED, %al
- xchgb %al, (laddr) /* an atomic "test and set" */
- cmpb $L_UNLOCKED, %al
- je done /* if equal, we got the lock */
- spin: cmpb $L_UNLOCKED, (laddr) /* spin in cache until unlocked */
- je loop /* then, try get lock again */
- jmp spin
- done:
- /PEEPON
- %mem laddr; lab loop, spin, done;
- /PEEPOFF
- loop: movb $L_LOCKED, %al
- movl laddr, %ecx
- xchgb %al, (%ecx) /* an atomic "test and set" */
- cmpb $L_UNLOCKED, %al
- je done /* if equal, we got the lock */
- spin: cmpb $L_UNLOCKED, (%ecx) /* spin in cache until unlocked */
- je loop /* then, try get lock again */
- jmp spin
- done:
- /PEEPON
- }
-
- asm void UNLOCK(laddr)
- {
- %reg laddr;
- movb $L_UNLOCKED, %al
- xchgb %al, (laddr) /* clear lock, "atomically" */
- %mem laddr;
- movb $L_UNLOCKED, %al
- movl laddr, %ecx
- xchgb %al, (%ecx) /* clear lock, "atomically" */
- }
-
- asm CLOCK(laddr)
- {
- %reg laddr; lab done;
- movb $L_LOCKED, %dl
- movl $L_SUCCESS, %eax
- xchgb %dl, (laddr) /* test and set lock */
- cmpb $L_UNLOCKED, %dl /* if we got it, return success */
- je done
- movl $L_FAILED, %eax /* else return failure */
- done:
- %mem laddr; lab done;
- movb $L_LOCKED, %dl
- movl laddr, %ecx
- movl $L_SUCCESS, %eax
- xchgb %dl, (%ecx) /* test and set lock */
- cmpb $L_UNLOCKED, %dl /* if we got it, return success */
- je done
- movl $L_FAILED, %eax /* else return failure */
- done:
- }
-
- #define INIT_LOCK(lp) UNLOCK(lp)
-
-
- S_INIT_LOCK(lock)
- slock_t *lock;
- {
- UNLOCK(lock);
- }
-
-
- S_LOCK(lock)
- register slock_t *lock;
- {
- LOCK(lock);
- }
-
-
- S_UNLOCK(lock)
- slock_t *lock;
- {
- UNLOCK(lock);
- }
-
- S_CLOCK(lock)
- slock_t *lock;
- {
- CLOCK(lock);
- }
-
- #endif i386
-